# -*- encoding:utf-8 -*-
# __author__ = 'chenyongbing'
# __poject__ = 'ops_cicd'
# __datetime__ = '2019/7/2'
# __name__ = 'yaml_helper'

from __future__ import unicode_literals
import json
from jinja2 import Template
import jinja2schema
import yaml

class YamlHelper():

    def parse_yaml_template(self, yaml_template):
        variables = jinja2schema.infer(yaml_template)
        return {k: '' for k in variables.keys()}


    def format_yaml_template(self, yaml_template,parameters):
        template = Template(yaml_template)
        yaml = template.render(**parameters)
        return yaml
    def find_values(self, id, obj):
        results = []
        def _find_values(id, obj):
            try:
                for key, value in obj.iteritems():
                    if key == id:
                        results.append(value)
                    elif not isinstance(value, basestring):
                        _find_values(id, value)
            except AttributeError:
                pass
    
            try:
                for item in obj:
                    if not isinstance(item, basestring):
                        _find_values(id, item)
            except TypeError:
                pass
    
        if not isinstance(obj, basestring):
            _find_values(id, obj)
        return results
    def add_env_to_yaml(self, yaml_text,envvars={}):
        # new_yaml_list = []
        # for yaml_object in yaml.safe_load_all(yaml_text):
        #     try:
        #         if yaml_object['kind'] == 'Deployment':
        #             for k,v in  envvars.items():
        #                 yaml_object.get('spec',{}).get('template',{}).get('spec',{}).get('containers',[])[0].get('env',[]).append({'name'.encode('utf-8'):k.encode('utf-8'),'value'.encode('utf-8'):v.encode('utf-8')})
        #         new_yaml_list.append(yaml.dump(yaml_object))
        #     except Exception as err:
        #         print(err.message)
        # return '---\n'.join(new_yaml_list)
        new_yaml_list = []
    
        for yaml_object in yaml.safe_load_all(yaml_text):
            nodes = self.find_values('env',yaml_object)
            for node in nodes:
                for k , v in envvars.items():
                    node.append({'name'.encode('utf-8'):k.encode('utf-8'),'value'.encode('utf-8'):v.encode('utf-8')})
            new_yaml_list.append(yaml.dump(yaml_object))
        return '---\n'.join(new_yaml_list)

    def insert_child_to_yaml(self, yaml_text,parent,child):
        def searchKey(json, name):
            if isinstance(json, dict):
                for key, value in json.items():
                    if name == key:
                        return value
                    else:
                        v = searchKey(value, name)
                        if v: return v
            elif isinstance(json, list):
                for data in json:
                    v = searchKey(data, name)
                    if v: return v
    
        new_yaml_list = []
        for yaml_object in yaml.safe_load_all(yaml_text):
            v = searchKey(yaml_object, parent)
            if v: v.update(child)
            new_yaml_list.append(yaml.dump(yaml_object))
        return '---\n'.join(new_yaml_list)

    def verify_yaml(self, yaml_text):
        try:
            yaml.safe_load_all(yaml_text)
            return True
        except Exception as err:
            return False

    def yaml_to_json(self, yaml_text):
        json = yaml.load(yaml_text, Loader=yaml.FullLoader)
        return json
if __name__=='__main__':
    yaml_template = '''apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: {{ namespace }}
  name: {{ appname }}-deployment
spec:
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  replicas: 1
  selector:
    matchLabels:
      app: {{ appname }}
  template:
    metadata:
      labels:
        app: {{ appname }}
    spec:
      imagePullSecrets:
        - name: {{ secret_name }}
      containers:
        - name: {{ appname }}
          image: {{ imagename }}
          resources:
            limits:
              memory: 2000Mi
              cpu: 1
            requests:
              memory: 1000Mi
              cpu: 0.2
          env:
            #设置环境变量，指定对应的apollo环境
            - name: ENV
              value: UAT
              #同步容器时区
            - name: TZ
              value: Asia/Shanghai
            - name: PROFILES
              value: test
            - name: JAVA_OPTS
              value: '-Xms500m -Xmx1000m'
            - name: JAVA_FILE_NAME
              value: /apps/{{ appname }}/{{ appname }}-*.jar
            - name: X_VAULT_TOKEN
              value: {{ x_vault_token }}
          ports:
            - containerPort: {{ port }}
          volumeMounts:
            - mountPath: /tmp/logs
              name: volume-cobra-logs-pvc
              subPath: {{ appname }}
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /actuator/health
              port: {{ port }}
              scheme: HTTP
            initialDelaySeconds: 60
            periodSeconds: 10
            successThreshold: 2
            timeoutSeconds: 2
          livenessProbe:
            failureThreshold: 5
            httpGet:
              path: /actuator/health
              port: {{ port }}
              scheme: HTTP
            initialDelaySeconds: 60
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 2
      terminationGracePeriodSeconds: 8
      volumes:
        - name: volume-cobra-logs-pvc
          persistentVolumeClaim:
            claimName: cobra-logs-pvc


---

apiVersion: v1
kind: Service
metadata:
  namespace: {{ namespace }}
  name: {{ appname }}
spec:
  type: NodePort
  selector:
    app: {{ appname }}
  ports:
    - port: {{ port }}
      targetPort: {{ port }}'''


    yh = YamlHelper()
    # print(yh.parse_yaml_template(yaml_template))
    print(yh.yaml_to_json(yaml_template))
    # parameters = {u'elk_redis_host': u'ELK_REDIS_HOST', u'service': u'SERVICE', u'image': u'IMAGE', u'reg_pull_secret': u'HARBOR', u'nacos_namespace': u'NACOS', u'elk_redis_auth': u'ELK_REDIS_AUTH', u'elk_redis_key': u'ELK_REDIS_KEY', u'elk_redis_port': u'ELK_REDIS_PORT', u'nacos_host': u'NACOS_HOST', u'k8s_namespace': u'K8S_NAMESPACE'}
    # 
    # yaml_text =  yh.format_yaml_template(yaml_template,parameters)
    # print(yaml_text)
    # print verify_yaml(yaml_text)
    # print add_env_to_yaml(yaml_text,{'a':'xxxx'})